package com.abel.web.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.validation.BindException;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;

import com.abel.domain.AuthPrincipal;
import com.abel.domain.AuthRequest;
import com.abel.domain.types.PersonType;
import com.abel.manager.AuthenticationManager;
import com.abel.manager.exception.AuthenticationException;
import com.abel.repository.exception.InsufficientPermissionException;
import com.abel.repository.exception.InvalidUserCredentialsException;
import com.abel.web.view.LoginViewBean;

public class AuthenticationController extends SimpleFormController {

	protected final Log logger = LogFactory.getLog(getClass());
	
	//injected using spring
	private AuthenticationManager authenticationManager;

	private String adminSuccessView;
	
	/* (non-Javadoc)
	 * @see org.springframework.web.servlet.mvc.SimpleFormController#onSubmit(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object, org.springframework.validation.BindException)
	 */
	@Override
	protected ModelAndView onSubmit(HttpServletRequest request,
			HttpServletResponse response, Object command, BindException errors)
			throws Exception {

		logger.debug("@AuthenticationController : onSubmit : entered");
		
		LoginViewBean bean = (LoginViewBean)command;
		
		//convert to domain
		AuthRequest authRequest = new AuthRequest();
		authRequest.setUserName(bean.getUserName());
		authRequest.setPassword(bean.getPassword());
		
		try {
			
			AuthPrincipal authPrincipal = authenticationManager.getAuthPrincipal(authRequest);
			if (authPrincipal == null) {
				logger.debug("@AuthenticationController : onSubmit : invalid login " + authRequest.getUserName());
				errors.rejectValue("", "error.null",null,"Invalid User ID or password.");
				return showForm(request,response,errors);
			}
		} 
		catch (AuthenticationException e) {

			logger.error("@AuthenticationController : onSubmit : Exception while authenticating after registering user " + e);
			errors.rejectValue("", "error.null",null,"We were not able to authenticate you at this point of time.  Please close the browser and login again");
			e.printStackTrace();
			return showForm(request,response,errors);
		}
		catch (InvalidUserCredentialsException e) {

			logger.error("@AuthenticationController : onSubmit : Exception while authenticating after registering user " + e);
			errors.rejectValue("", "error.null",null,"The user id or password entered in invalid.  Please correct it and relogin");
			e.printStackTrace();
			return showForm(request,response,errors);
		}
		catch (InsufficientPermissionException e) {

			logger.error("@AuthenticationController : onSubmit : Exception while authenticating after registering user " + e);
			errors.rejectValue("", "error.null",null,"We were not able to authenticate you at this point of time.  Please close the browser and login again");
			e.printStackTrace();
			return showForm(request,response,errors);
		}
		
		//if the user is a superuser, he/she will be redirected to the admin dashboard
		if (bean.getPersonType() == PersonType.Administrator
				|| bean.getPersonType() == PersonType.Superuser) {
			
			return new ModelAndView("redirect:" + getAdminSuccessView());
		}
		else {
			
			return new ModelAndView("redirect:" + getSuccessView());
		}
	}


	/* (non-Javadoc)
	 * @see org.springframework.web.servlet.mvc.AbstractFormController#formBackingObject(javax.servlet.http.HttpServletRequest)
	 */
	@Override
	protected Object formBackingObject(HttpServletRequest request)
			throws Exception {
		
		LoginViewBean viewBean = new LoginViewBean();
		
		if (request.getRequestURL().indexOf("adminlogin.xhtm") != -1) {
			
			viewBean.setPersonType(PersonType.Administrator);
		}
		return viewBean;
	}

	
	public void setAuthenticationManager(AuthenticationManager authenticationManager) {
		this.authenticationManager = authenticationManager;
	}


	/**
	 * @return the adminSuccessView
	 */
	public String getAdminSuccessView() {
		return adminSuccessView;
	}


	/**
	 * @param adminSuccessView the adminSuccessView to set
	 */
	public void setAdminSuccessView(String adminSuccessView) {
		this.adminSuccessView = adminSuccessView;
	}

	
}
